home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_geomview.idb / usr / freeware / lib / geomview / maple / gvplot.mapleV4.z / gvplot.mapleV4
Encoding:
Text File  |  1999-01-26  |  26.4 KB  |  733 lines

  1. ##########################
  2. ##
  3. ##    Title   :  writeoogl,  a package for converting maple PLOT3D
  4. ##                objects to Geomview data objects.
  5. ##         gvplot,     interactive pipe to Geomview from Maple
  6. ##
  7. ##    Created :  Dec 5 1993
  8. ##
  9. ##    Authors :  Frederick Wicklin  and 
  10. ##         Stuart Levy
  11. ##               The Geometry Center
  12. ##         1300 South Second Street
  13. ##         Minneapolis, MN 55454
  14. ##
  15. ##               <fjw@geom.umn.edu>
  16. ##               <slevy@geom.umn.edu>
  17. ##
  18. ##    Documentation :   currently ?gvplot or ?writeoogl or ?geomview
  19. ##
  20. ##    History
  21. ##              fjw    9/21/93    initial maple->geomview for Maple VR2
  22. ##         slevy 11/27/93    interactive geomview pipe; 
  23. ##                backwards compatable to Maple V
  24. ##           fjw   11/29/93    debugging; added color options
  25. ##
  26. ##              lr (renggli@math.fsu.edu) 03/28/97
  27. ##                   modifications for Maple VR4 (replaced gc() calls)
  28. ##
  29. ##
  30. ##    Usage:       readlib(gvplot);
  31. ##          (optional) gvcommand := `geomview  initial-options ...`;
  32. ##          (optional) gvdirectories := `/some/dir/ectory:/other/dir...`;
  33. ##        3dplot_struct := plot3d( ... ):
  34. ##         writeoogl(`filename`, 3dplot_struct);
  35. ##        gvplot(3dplot_struct);
  36.  
  37. # To search for "geomview" and "togeomview" in directories which might not
  38. # be on the default UNIX search path, list those director(ies) here, as in
  39. #    default_gvdirectories := `/u/geom/bin:/usr/local/bin:`
  40. # or, set the "gvdirectories" variable before invoking gvplot().
  41.  
  42. default_gvdirectories := ``:
  43.  
  44. # To start geomview with non-default options, or to start another program
  45. # via gvplot, put its name and initial arguments here in place of `geomview`,
  46. # or set the variable "gvcommand" before invoking gvplot().
  47. # Changing default_gvcommand, then resaving gvplot.m, alters the default for
  48. # all users; setting the gvcommand variable changes it for just your session.
  49.  
  50. default_gvcommand := `geomview`:
  51.  
  52.  
  53. ### Upon invoking the geomview package, maple creates a global
  54. ### variable UsEr_ID__ which is assigned a "random" number.
  55. ### This variable is used to create user-specific files in /tmp.
  56. ##################################################################
  57. # There doesn't seem to be any explicit test for Maple V1 vs. V2,
  58. # but all V1 plot objects seem to begin with FUNCTION, so use that fact
  59. # to detect that we must be careful not to print invalid float constants.
  60. ##################################################################
  61. `oogl/lprn` := `oogl/lprnV2`:
  62.  
  63. writeoogl := proc()
  64.    global  `oogl/lprn`;
  65.    local header, item, ps, zlist, plist, llist, ppoint, pcolor, appear,
  66.         i, j, totl, xrange, yrange, nx, ny, savedprintbytes,
  67.         coloron,colorlist,ccnt, totalverts;
  68.    options `Copyright 1993 by Frederick Wicklin and Stuart Levy, Geometry Center`;
  69.  
  70.    if nargs > 2 or nargs = 0 then
  71.      ERROR(`Usage:writeoogl(``filename``,3dplot_struct); OR writeoogl(3dplot_struct);`)
  72.    fi;
  73.    ps := args[nargs];
  74.    if not type(ps, PLOT3D) then ERROR(`Invalid plot structure`,ps,
  75.     `; must be of type PLOT3D, as from plot3d(), tubeplot(), spacecurve(), etc.`)
  76.    fi;
  77.    if nargs = 2 and not type(args[1], string) then
  78.     ERROR(`Invalid file name (not string)`, args[1])
  79.    fi;
  80.    if nops(ps) < 1 then ERROR(`Empty 3D plot structure!`) fi;
  81.  
  82.    ##################################################################
  83.    # When run in command-line mode, Garbage Collection (GC)         #
  84.    # messages printed to terminal can interfere with the data flow. #
  85.    # Therefore suppress GC during writing of GeomView data          #
  86.    ##################################################################
  87.    if nargs = 2 then
  88.        savedprintbytes:=kernelopts( printbytes):
  89.        kernelopts( printbytes=false):
  90.        print(`Saving Maple 3D structs to Geomview file`, args[1]);
  91.        writeto(args[1]);
  92.    fi;
  93.    xrange := 'xrange';        # nullify this local variable
  94.    appear := find_appearance(1, ps);
  95.    lprint( appear, `{LIST` );
  96.  
  97.    ##################################################################
  98.    ### BEGIN main loop over all 3D plots (may be a list of plots) ###
  99.    ##################################################################
  100.    for item in ps do
  101.      coloron := FALSE;        # default is no color info
  102.      header := op(0,item);
  103.  
  104.      if header = FUNCTION then
  105.     # Maple V1 only:  FUNCTION( f(x,y),  xrange, yrange )
  106.     # or    FUNCTION( x(u,v), y(u,v), z(u,v),  u = u0..u1, v = v0..v1 )
  107.     xrange := op(nops(item)-1, item);
  108.     if type(xrange, `=`) then xrange := op(2, xrange) fi;
  109.     yrange := op(nops(item), item);
  110.     if type(yrange, `=`) then yrange := op(2, yrange) fi;
  111.     # Maple V1 -- don't trust lprint()
  112.     `oogl/lprn` := `oogl/lprnV1`;
  113.  
  114.      ###########################  GRID   ############################
  115.      # EX: plot3d( f(x,y), x=xmin..xmax, y=ymin..ymax] 
  116.      # Saving Maple GRID struct to geomview ZMESH struct
  117.      # Maple V1:  FUNCTION( f(x,y), xrange,yrange ) followed by GRID( zlist )
  118.      #  In Maple V1, we might see either ZMESH-style data (only Z per vertex)
  119.      #    or a full 3-D mesh (x,y,z per vertex).  Just check the first
  120.      #    vertex to see.
  121.      # Maple V2:  GRID( xrange, yrange, zlist )
  122.      #    Maple V2 uses GRID only for ZMESH-style data,
  123.      #    and uses a MESH header for meshes with general 3-D verts.
  124.      ###############################################################
  125.      elif header = GRID then
  126.     if type(xrange, `..`) then
  127.         zlist := item
  128.     else                # this is typical VR2 route
  129.         xrange := op(1, item);
  130.         yrange := op(2, item);
  131.         zlist := op(3, item);
  132.         #######################################################
  133.         # if color, then there are 4 possibilities:
  134.         # colorlist = COLOR(HUE, h[1],...,h[nops[colorlist])
  135.         # colorlist = COLOR(HUE, h)
  136.         # colorlist = COLOR(RGB, r[1],g[1],b[1],...)
  137.         # colorlist = COLOR(RGB, r,g,b)
  138.         # Convert HUES to an RGB value using HSV2RGB and
  139.         # (assume that Maple uses s=v=1).  Add a 1 at the end of
  140.         # the list for geomview's "alpha": 0<=>transparent, 1<=>opaque
  141.         #######################################################
  142.         if( nops(item)>3 ) then 
  143.         colorlist := find_colorlist(4, item);
  144.         coloron := op(1,colorlist); # either RGB, HUE, or FALSE
  145.         fi;
  146.     fi;
  147.     nx := nops(zlist);
  148.     ny := nops(op(1,zlist));
  149.     if type(op(1, op(1,zlist)), list) then
  150.         lprint(`{ { MESH`, ny, nx)
  151.     else   # scale this data by wrapping it in transformation matrix
  152.         lprint(`{ INST transform { `);    
  153.         `oogl/lprn`( [0, (op(2,yrange)-op(1,yrange)) / (ny-1), 0, 0] );
  154.         `oogl/lprn`( [(op(2,xrange)-op(1,xrange)) / (nx-1), 0, 0, 0] );
  155.         lprint(0, 0, 1, 0);
  156.         `oogl/lprn`( [op(1,xrange), op(1,yrange), 0, 1] );
  157.         if(coloron = FALSE) then
  158.         lprint(`  } geom { ZMESH`, ny, nx);      # gv type
  159.         else
  160.         lprint(`  } geom { CZMESH`, ny, nx);      # color gv type
  161.         fi;
  162.     fi;
  163.     ccnt := 2;            # set color counter to 2
  164.     for plist in zlist do
  165.         for ppoint in plist do     
  166.            `oogl/lprn`(ppoint);
  167.            if (coloron = HUE) and nops(colorlist)>2 then 
  168.              lprint(HSV2RGB(op(ccnt,colorlist), 1,1), 1);
  169.              ccnt := ccnt + 1;
  170.            elif (coloron = HUE) and nops(colorlist)=2 then
  171.          lprint(HSV2RGB(op(2,colorlist), 1,1), 1);
  172.            elif (coloron = RGB) and nops(colorlist)>4 then 
  173.              lprint(op(ccnt,colorlist),op(ccnt+1,colorlist),op(ccnt+2,colorlist),1);
  174.              ccnt := ccnt + 3;
  175.            elif (coloron = RGB) and nops(colorlist)=4 then
  176.          lprint(op(2,colorlist),op(3,colorlist),op(4,colorlist), 1);
  177.            fi;
  178.         od;
  179.     od;
  180.     lprint( `} }`);
  181.  
  182.      ###########################  MESH   ###########################
  183.      # EX: plot3d( [x(s,t), y(s,t), z(s,t)], s=smin..smax, t=tmin..tmax] 
  184.      # Saving Maple MESH struct to geomview MESH struct
  185.      ###############################################################
  186.      elif header = MESH  then
  187.     llist := op(1, item):
  188.         if( nops(item)>1 ) then
  189.           colorlist := find_colorlist(2, item);
  190.           coloron := op(1,colorlist); # either RGB, HUE, or FALSE
  191.         fi;
  192.     if(coloron=FALSE) then 
  193.        lprint(`{ MESH ` );          # gv type
  194.     else 
  195.        lprint(`{ CMESH ` );          # color gv type
  196.     fi;
  197.     lprint( nops(llist));         # num x elements
  198.     lprint( nops(op(1,llist)) );    # num y elements
  199.     # Maple store points in row-dominant manner
  200.         # But geomview want column-dominant, so need to 
  201.     # print out the transpose of the matrix in the plot3d struct
  202.     nx := nops(llist);        # maple rows
  203.     ny := nops(op(1,llist));    # maple cols
  204.     for j from 1 to ny do
  205.       for i from 1 to nx do 
  206.         ppoint := op(j, op(i,llist));
  207.         `oogl/lprn`(ppoint);     
  208.              if (coloron = HUE) and nops(colorlist)>2 then
  209.                lprint(HSV2RGB(op((i-1)*ny+j +1,colorlist), 1,1), 1);
  210.              elif (coloron = HUE) and nops(colorlist)=2 then
  211.                lprint(HSV2RGB(op(2,colorlist), 1,1), 1);
  212.              elif (coloron = RGB) and nops(colorlist)>4 then
  213.                lprint(op(3*((i-1)*ny+j-1)+2,colorlist),op(3*((i-1)*ny+j-1)+3,colorlist),op(3*((i-1)*ny+j-1)+4,colorlist),1);
  214.              elif (coloron = RGB) and nops(colorlist)=4 then
  215.                lprint(op(2,colorlist),op(3,colorlist),op(4,colorlist), 1);
  216.              fi;
  217.       od;
  218.     od;
  219.     lprint( `}`);
  220.  
  221.      ###########################  CURVES  ##########################
  222.      # EX: spacecurve( [x(t), y(t), z(t)], t=tmin..tmax] 
  223.      # Saving Maple CURVES struct to geomview VECT struct
  224.      ###############################################################
  225.      elif header = CURVES then
  226.     llist := select(type, item, list);
  227.         if( nops(item)>1 ) then
  228.           colorlist := find_colorlist(2, item);
  229.           coloron := op(1,colorlist); # either RGB, HUE, or FALSE
  230.         fi;
  231.         lprint(`{ VECT `);          # gv type
  232.             # Number of polylines, total vertices.
  233.     totalverts := sum('nops(op(i,llist))', 'i'=1..nops(llist));
  234.     lprint(nops(llist), totalverts);
  235.     if coloron=FALSE then
  236.       lprint(1);            # One color in all
  237.       lprint(seq(nops(op(i,llist)), i=1..nops(llist))); # Vertex counts
  238.       lprint(1, 0 $ 'i'=2..nops(llist));        # Color counts.
  239.     else
  240.       lprint(totalverts);        # Total number of colors, 1 per vert
  241.       lprint(seq(nops(op(i,llist)), i=1..nops(llist))); # Vertex counts
  242.       lprint(seq(nops(op(i,llist)), i=1..nops(llist))); # color per vert
  243.     fi;
  244.     for plist in llist do
  245.       for ppoint in plist do         # print all vertices
  246.         `oogl/lprn`(ppoint);     
  247.       od
  248.     od;
  249.     if coloron=FALSE then
  250.       lprint(1,1,1,1);        # color RGBA = white and opaque
  251.         elif (coloron = HUE) and nops(colorlist)>2 then
  252.       for ccnt from 2 to nops(colorlist) do
  253.         lprint(HSV2RGB(op(ccnt,colorlist), 1,1), 1);
  254.           od;
  255.         elif (coloron = HUE) and nops(colorlist)=2 then
  256.           for ccnt from 1 to nops(llist) do
  257.             lprint(HSV2RGB(op(2,colorlist), 1,1), 1);
  258.       od;
  259.         elif (coloron = RGB) and nops(colorlist)>4 then
  260.           for ccnt from 2 by 3 to nops(colorlist) do
  261.         lprint(op(ccnt,colorlist),op(ccnt+1,colorlist),op(ccnt+2,color\list),1);
  262.       od;
  263.         elif (coloron = RGB) and nops(colorlist)=4 then
  264.           for ccnt from 1 to nops(llist) do
  265.         lprint(op(2,colorlist),op(3,colorlist),op(4,colorlist),1);
  266.       od;
  267.         fi;
  268.     lprint( `}`);
  269.  
  270.      #########################  POLYGONS  ##########################
  271.      #EX:polygonplot3d([seq([seq([x(s,t),y(s,t),z(s,t)],s=smin..smax],tmin..tmax])):
  272.      # Polygons are handled differently than the other objects w/r/t
  273.      # color.  Leave color alone and let user change color using geomview.
  274.      ###############################################################
  275.      elif header = POLYGONS then
  276.     pcolor := i $ i=1..0;    # Empty sequence
  277.     totl := 0: nx := 0:     # use nx to count number of polygons
  278.     for llist in item do        # sequence of lists POLY(),COLOR(),
  279.       if type(llist,list) then
  280.         nx := nx + 1;        # number of polygons
  281.         totl := totl + nops(llist);    # compute total number of vertices
  282.       fi
  283.     od;
  284.  
  285.     lprint(find_appearance(1, item));
  286.  
  287. #    if coloron=FALSE then
  288.       lprint(`{ OFF `);          # gv type
  289. #    else 
  290. #      lprint(`{ COFF `);        # color
  291. #    fi;
  292.     lprint(totl, nx, 0);    # total verts,polygons,"edges"(not used!)
  293.     for llist in item do 
  294.       if type(llist,list) then
  295.             for ppoint in llist do    
  296.           `oogl/lprn`(ppoint);         # List of vertices
  297.         od;
  298.       fi;
  299.     od;
  300.     lprint(``);
  301.     totl := 0;
  302.     for llist in item do
  303.       if type(llist,function) 
  304.                and (op(0,llist)=COLOR or op(0,llist)=COLOUR) then
  305.         colorlist := llist;
  306.         if op(1,llist)=HUE and nops(colorlist)=2 then
  307.             pcolor := HSV2RGB(op(2,colorlist),1,1);  # use ppoint for RGB
  308.         elif op(1,llist)=RGB and nops(colorlist)=4 then
  309.         pcolor := op(2..4,colorlist);
  310.         fi;
  311.       elif type(llist,list) then
  312.          ## There are only two possibilities for POLYGONS ##
  313.          ## In both cases, it means entire polygon is same color ##
  314.          lprint( nops(llist), i $ i=totl..totl+nops(llist)-1, ` `, pcolor);
  315.          totl := totl + nops(llist);
  316.        fi;
  317.     od;
  318.     lprint( `}`);
  319.  
  320.      #########################   POINTS   ##########################
  321.      #EX:PLOT3D(POINTS([0,0,1],[1,0,0],[0,1,0]));
  322.      ###############################################################
  323.      elif header = POINTS then
  324.     lprint(`{ VECT`, nops(item), nops(item), 0);
  325.     for plist in item do lprint(`1`) od;
  326.     lprint(``);
  327.     for plist in item do lprint(`0`) od;
  328.     lprint(``);
  329.     for ppoint in item do
  330.         `oogl/lprn`(ppoint)
  331.     od;
  332.     lprint(`}`);
  333.  
  334.      ###########################  TEXT  ############################
  335.      # 3D plots using the "plots" package may include TEXT
  336.      # This is not supported
  337.      ###############################################################
  338.      elif header = TEXT then
  339.     print(` `);
  340.      fi;
  341.    od;  # END main for loop
  342.  
  343.    lprint( `}`);
  344.    if nargs = 2 then
  345.     writeto(terminal);
  346.      kernelopts( printbytes=savedprintbytes):
  347.    fi;
  348.    NULL;
  349. end:
  350.  
  351.  
  352. gvplot := proc()
  353.    global UsEr_ID__, gvcommand, default_gvcommand, gvdirectories, default_gvdirectories;
  354.    local gvname, gvcmd, gvdirs, ps, savedprintbytes, tmp_fname;
  355.    options `Copyright 1993 by Frederick Wicklin and Stuart Levy, Geometry Center`;
  356.    ### Set up filename to use as temporary site for data.      ###
  357.    ### Take file in /tmp and postfix number which is (hopefully) ###
  358.    ### independent of users.  Eg, if user1 and user2 are both    ###
  359.    ### using writeoogl, then they will be writing to different   ###
  360.    ### files. This is UNIX specific (but so is Geomview).     ### 
  361.    if UsEr_ID__ = 'UsEr_ID__' then
  362.     UsEr_ID__ := (round( rand() * (time()+1) ) mod 9999) + 1;
  363.    fi;
  364.    tmp_fname := `Maple`.(UsEr_ID__);
  365.  
  366.    ### Let user specify, via "gvcommand" and "gvdirectories" global vars,
  367.    ### which program/args to run when invoking geomview,
  368.    ### and how to set the search path to find it and togeomview.
  369.  
  370.    if gvcommand <> 'gvcommand'
  371.     then gvcmd := gvcommand
  372.     else gvcmd := default_gvcommand
  373.    fi;
  374.    if gvdirectories <> 'gvdirectories'
  375.     then gvdirs := gvdirectories
  376.     else gvdirs := default_gvdirectories
  377.    fi;
  378.     
  379.    ps := args[nargs];
  380.    gvname := `Maple`;
  381.  
  382.    if nargs < 1 or nargs > 2 then
  383.     ERROR(`Usage: gvplot(3dplot_structure)  -or-  gvplot(``name``, 3dplot_structure)`);
  384.    fi;
  385.    if nargs > 1 then gvname := args[1] fi;
  386.    if not type( ps, PLOT3D) then 
  387.       ERROR(`Invalid plot structure`,ps,
  388.     `; must be of type PLOT3D, as from plot3d(), tubeplot(), spacecurve(), etc.`)
  389.    fi;
  390.    # start geomview reading from stdin
  391.    if system( `PATH=` . gvdirs . `:$PATH togeomview -Mcp `.tmp_fname.` `.gvcmd.`</dev/null` ) <> 0 then
  392.     ERROR(`gvplot: togeomview: Can't start a copy of geomview.  `.
  393.         `If "togeomview" or "geomview" were not found `.
  394.         `try setting the variable "gvdirectories" to the name of the directory where `.
  395.         `they're installed (or to a colon-separated list of directories).`);
  396.    fi;
  397.    savedprintbytes:=kernelopts( printbytes):
  398.    kernelopts( printbytes=false):
  399.    writeto(`/tmp/geomview/`.tmp_fname);
  400.    lprint(`(geometry`, gvname);
  401.    writeoogl( ps );
  402.    lprint(`)`);
  403.    writeto(terminal);
  404.    kernelopts( printbytes=savedprintbytes):
  405.    NULL;
  406. end:
  407.  
  408. gvcommand := proc()
  409.    global UsEr_ID__, gvcommand, default_gvcommand, gvdirectories, default_gvdirectories;
  410.    local gvname, gvcmd, gvdirs, ps, savedprintbytes, tmp_fname;
  411.    options `Copyright 1993 by Frederick Wicklin and Stuart Levy, Geometry Center`;
  412.    ### Set up filename to use as temporary site for data.      ###
  413.    ### Take file in /tmp and postfix number which is (hopefully) ###
  414.    ### independent of users.  Eg, if user1 and user2 are both    ###
  415.    ### using writeoogl, then they will be writing to different   ###
  416.    ### files. This is UNIX specific (but so is Geomview).     ### 
  417.    if UsEr_ID__ = 'UsEr_ID__' then
  418.     UsEr_ID__ := (round( rand() * (time()+1) ) mod 9999) + 1;
  419.    fi;
  420.    tmp_fname := `Maple`.(UsEr_ID__);
  421.  
  422.    ### Let user specify, via "gvcommand" and "gvdirectories" global vars,
  423.    ### which program/args to run when invoking geomview,
  424.    ### and how to set the search path to find it and togeomview.
  425.  
  426.    if gvcommand <> 'gvcommand'
  427.     then gvcmd := gvcommand
  428.     else gvcmd := default_gvcommand
  429.    fi;
  430.    if gvdirectories <> 'gvdirectories'
  431.     then gvdirs := gvdirectories
  432.     else gvdirs := default_gvdirectories
  433.    fi;
  434.  
  435.    # start geomview reading from stdin
  436.    if system( `PATH=` . gvdirs . `:$PATH togeomview -Mcp `.tmp_fname.` `.gvcmd.`</dev/null` ) <> 0 then
  437.     ERROR(`gvplot: togeomview: Can't start a copy of geomview.  `.
  438.         `If "togeomview" or "geomview" were not found `.
  439.         `try setting the variable "gvdirectories" to the name of the directory where `.
  440.         `they're installed (or to a colon-separated list of directories).`);
  441.    fi;
  442.    savedprintbytes:=kernelopts( printbytes):
  443.    kernelopts( printbytes=false):
  444.    writeto(`/tmp/geomview/`.tmp_fname);
  445.    lprint(args);
  446.    writeto(terminal);
  447.    kernelopts( printbytes=savedprintbytes):
  448.    NULL;
  449. end:
  450.  
  451. # possible gvplot enhancements:
  452. #  allow remote display?
  453. #  Maybe use a two-step Rube Goldberg hookup with an external converter
  454. #  that directly reads lprint() format.  Likely to be faster for large objects.
  455. #  Then gvplot would read
  456. #  gvplot := proc()
  457. #    ...
  458. #    if system(`togeomview -Mcp Maple.raw  maple2oogl -togeomview -Mcp Maple`)<>0
  459. #    then ERROR(...) fi;
  460. #    writeto(`/tmp/geomview/Maple.raw`);
  461. #    lprint(`(geometry`, gvname, `<<`);
  462. #    lprint(3dplot_struct);
  463. #    lprint(`>>)`);
  464. #    writeto(terminal);
  465. #  end:
  466. # and writeoogl would read
  467. # writeoogl := proc()
  468. #    ...
  469. #    if system(cat(`togeomview -Mcp Maple.rawdata  maple2oogl -o `, fname)) <> 0
  470. #    then ERROR(...) fi;
  471. #    writeto(`/tmp/geomview/Maple.rawdata`);
  472. #    lprint(`<<', 3dplot_string, `>>');
  473. #    writeto(terminal);
  474. #  end:
  475. #
  476. # Here 'togeomview' is actually being used to start 'maple2oogl' rather
  477. # than geomview itself.  In the first case, maple2oogl -togeomview would
  478. # invoke code to start a copy of geomview.
  479.  
  480. # Help information for writeoogl
  481. `help/text/writeoogl` := TEXT(
  482. ` `,
  483. `HELP FOR: writeoogl, gvplot                        `,
  484. ` `,
  485. `CALLING SEQUENCE:                            `,
  486. `    readlib(gvplot):                        `,
  487. `    writeoogl( ``filename``, 3dplot_struct );            `,
  488. `    writeoogl( 3dplot_struct );                    `,
  489. `    gvplot( 3dplot_struct );                    `,
  490. `    gvplot( ``geomview_name``, 3dplot_struct )            `,
  491. ` `,
  492. `PARAMETERS:                                `,
  493. `    filename        the file which will contain the Geomview data    `,
  494. `    3dplot_struct    a Maple PLOT3D data structure            `,
  495. `    geomview_name    name of the object in the Geomview browser    `,
  496. ` `,
  497. `SYNOPSIS:                                 `,
  498. `    writeoogl() accepts Maple PLOT3D structures and writes files    `,
  499. `    readable by Geomview.  gvplot() converts Maple PLOT3D structures`,
  500. `    and displays them immediately using Geomview, starting a copy of`,
  501. `    Geomview if necessary.`,
  502. ``,
  503. `    Supported data types include the Maple structures MESH, GRID,    `,
  504. `    CURVES, POINTS, and POLYGONS.    `,
  505. `    See ?plot3d[structure] for more information on Maple PLOT3D types.`,
  506. ` `,
  507. `    The Maple MESH and GRID structures are translated into Geomview's`,
  508. `    MESH and ZMESH objects, respectively, Maple CURVES and POINTS`,
  509. `    become VECT objects, and Maple POLYGONS becomes an OFF object.`,
  510. ` `,
  511. `    The Maple TEXT structure is not supported. Color information is`,
  512. `    supported for all objects.`,
  513. ``,
  514. `    The form writeoogl(filename, plot_struct) writes data in OOGL`,
  515. `    (Geomview) form to the given file; writeoogl(plot) writes to the`,
  516. `    current output stream as selected by writeto().`,
  517. ``,
  518. `    gvplot() normally starts the program "geomview", with no options;`,
  519. `    to specify something else, set the variable "gvcommand", as in:`,
  520. `       gvcommand := ``/usr/local/bin/gv -wpos 200x200 -c startup.gv``;`,
  521. `    before invoking gvplot().  Also, if the programs "geomview" or`,
  522. `    "togeomview" are not on your UNIX search path, set the variable`,
  523. `       gvdirectories := ``/some/dir/ectory:/some/other/directory``;`,
  524. `    to the appropriate directory (or directories separated by colons).`,
  525. ` `,
  526. `EXAMPLES:                                `,
  527. `    readlib(gvplot):                        `,
  528. `    my_plot := plot3d(sin(x+y), x=-Pi..Pi, y=-Pi..Pi):        `,
  529. `    writeoogl( ``sinxy.mesh``, my_plot );                `,
  530. `                  Saving Maple 3D structs to Geomview file, sinxy.mesh    `,
  531. `    steiner := plot3d([ sin(2*x)*(cos(y))^2, sin(x)*sin(2*y),    `,
  532. `          cos(x)*sin(2*y)], x=-Pi..Pi, y=-Pi..Pi):            `,
  533. `    writeoogl( ``steiner.mesh``, steiner);                `,
  534. `                  Saving Maple 3D structs to Geomview file, steiner.mesh`,
  535. `    # Display it in geomview directly                `,
  536. `    gvplot( steiner );                        `,
  537. `    # load in the plots package                    `,
  538. `    with(plots):                            `,
  539. `    trefoil := spacecurve([ -2*cos(t)- 1/2*cos(5*t)+ 3*sin(2*t),    `,
  540. `              -3*cos(2*t)+ 2*sin(t)- 1/2*sin(5*t), 2*cos(3*t), t=0..2*Pi]):`,
  541. `    writeoogl( ``trefoil.vect``, trefoil);                `,
  542. `                  Saving Maple 3D structs to Geomview file, trefoil.vect`,
  543. `    tetrahedra := [[1,0,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,0,1],[0,1,0]], `,
  544. `                  [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,1,0],[-1,0,0]]:`,
  545. `    Tplot :=polygonplot3d([tetrahedra]):                `,
  546. `    writeoogl( ``tetrahedra.off``, Tplot);                `,
  547. `                  Saving Maple 3D structs to Geomview file, tetrahedra.off`,
  548. `    # you can even create a single file with multiple objects    `,
  549. `    all_objs := display3d( {my_plot, steiner, trefoil, Tplot} ):    `,
  550. `    writeoogl( ``all.list``, all_objs );                `,
  551. `                  Saving Maple 3D structs to Geomview file, all.list    `,
  552. ` `,
  553. `SEE ALSO: plot3d[structure]                        `
  554.  
  555. ):
  556.  
  557. `help/text/gvplot`   := `help/text/writeoogl`:
  558. `help/text/geomview` := `help/text/writeoogl`:
  559.  
  560.  
  561. # Convert number to string, avoiding excess digits and avoiding Maple V1's
  562. # propensity to emit Float(mantissa,exponent) rather than ordinary exponential
  563. # notation!
  564.  
  565. `oogl/cvs` := proc(v)
  566.     local sign, absmant;
  567.     options `Copyright 1993 by Stuart Levy, Geometry Center`;
  568.     if type(v, float) then
  569.         absmant := cat(abs(op(1,v)));
  570.         sign := substring(`-`, 1..1-signum(v));
  571.         if abs(v) >= 1 then
  572.         if(op(2,v) >= 0) then
  573.             cat(op(1,v), '0' $ op(2,v))
  574.         else
  575.             cat(
  576.             sign,
  577.             substring(absmant, 1..length(absmant)+op(2,v)),
  578.             `.`,
  579.             substring(absmant, length(absmant)+op(2,v)+1..8)
  580.             )
  581.         fi
  582.         elif abs(v) > .000001  then
  583.         cat( sign,
  584.             substring( `.0000000`, 1 .. 1-length(absmant)-op(2,v) ),
  585.             substring(absmant, 1..7)
  586.         )
  587.         else
  588.         cat( sign,
  589.             `.`, substring( absmant, 1..7),
  590.             `e`, op(2,v) + length(absmant)
  591.         )
  592.         fi
  593.     elif type(v, realcons) then
  594.         cat(v)
  595.     fi;
  596. end:
  597.  
  598. #
  599. # lprint a number, or a list of numbers.
  600. #
  601. `oogl/lprnV1` := proc (v)
  602.     local i;
  603.     options `Copyright 1993 by Stuart Levy, Geometry Center`;
  604.     if type(v, list) then
  605.         lprint( ' `oogl/cvs`(v[i]) ' $ i=1..nops(v) );
  606.     elif type(v,float) and abs(v) <= .1 then
  607.         lprint(`oogl/cvs`(v));
  608.     elif type(v, realcons) then
  609.         lprint(v);
  610.     else
  611.         lprint(`0 #`);
  612.     fi;
  613. end:
  614.  
  615.  
  616. # Ditto, but assume we're Maple V2, which prints floating constants
  617. # in acceptable form.  Don't bother to reformat them.
  618.  
  619. `oogl/lprnV2` := proc(v)
  620.     local i;
  621.     options `Copyright 1993 by Stuart Levy, Geometry Center`;
  622.     if type(v, list) then
  623.         lprint( 'v[i]' $ i = 1..nops(v) );    # Print on one line
  624.     elif type(v, realcons) then
  625.         lprint(v);
  626.     else
  627.         lprint(`0 #`);
  628.     fi
  629. end:
  630.  
  631. ###############################################################
  632. ## HSV2RGB converts Maple Hues to RGB colors.
  633. ## The HUEs used are in [0,1] so assume that S=V=1 (this is close)
  634. ## The following algorithm is from Computer Graphics
  635. ## By Foley, vanDam, Feiner, Hughes, 2nd Ed. Addison-Wesley
  636. ## p 593
  637. ##
  638. ## Adapted by fjw 11/29/93
  639. ## Input: (h,s,v) in [0,1]^3
  640. ## Output: sequence r,b,g  each in [0,1]
  641. ###############################################################
  642. HSV2RGB := proc( h,s,v )
  643.   local hh,ip,fp,p,q,t;
  644.   options `Copyright 1990 by Foley, vanDam, Feiner, Hughes`;
  645.   if (s = 0) then     # color on B/W center line
  646.     if (h<0) then     # There is no hue,ie, hue undefined
  647.       RETURN( v,v,v );
  648.     else
  649.       ERROR(`Undefined color`);
  650.     fi;
  651.   else
  652.     if (h>1) then hh:=1 fi;
  653.     hh := 6*h;         # hh now in [0,6]
  654.     ip := floor(hh);   # ip is integer part of h
  655.     fp := hh - ip;     # fp is fractional part of h
  656.     p  := v*(1-s); 
  657.     q  := v*(1-(s*fp));
  658.     t  := v*(1-(s*(1-fp)));
  659.     if (ip=0) then 
  660.     RETURN( v,t,p );
  661.     elif (ip=1) then
  662.         RETURN( q,v,p );
  663.     elif (ip=2) then
  664.     RETURN( p,v,t );
  665.     elif (ip=3) then
  666.     RETURN( p,q,v );
  667.     elif (ip=4) then
  668.     RETURN( t,p,v );
  669.     else 
  670.     RETURN( v,p,q );
  671.     fi;
  672.   fi;
  673. end:
  674.  
  675.  
  676. ########################################################
  677. # find_colorlist
  678. # input: n       where to start looking for color data
  679. #        item    what list to search
  680. # output: list of color information or NULL list
  681. ########################################################
  682. find_colorlist := proc(n,item)
  683.   local i;    
  684.   options `Copyright 1993 by Frederick Wicklin, Geometry Center`;
  685.   for i from n to nops(item) do
  686.      if type(op(i,item),function) and (op(0,op(i,item))=COLOR or op(0,op(i,item))=COLOUR) then
  687.        RETURN(op(i,item))
  688.     fi;
  689.   od;
  690.   RETURN([FALSE]);  # no color info found
  691. end:
  692.  
  693. ########################################################
  694. # find_appearance
  695. # input: n    index to start seeking color data
  696. #     list    list to search
  697. # output: argument of STYLE option (e.g. `PATCH`) or [] list.
  698. ########################################################
  699. find_appearance := proc(n, list)
  700.   local i, part, ap, color, colortype;
  701.   ap := ``; color := ``;
  702.   for i from n to nops(list) do
  703.     part := op(i,list);
  704.     if type(part,function) and (op(0,part)=COLOR or op(0,part)=COLOUR) then
  705.     colortype := op(1,part);
  706.     if colortype = HUE and nops(part) = 2 then
  707.       color := [HSV2RGB(op(2,part), 1, 1)]
  708.     elif colortype = RGB and nops(part) = 4 then
  709.       color := [op(2..4,part)]
  710.     fi
  711.     # Otherwise, this "color" tag isn't for us
  712.     elif type(part,function) and op(0,part) = STYLE then
  713.     if op(1,part) = PATCH then
  714.        ap := cat(ap, ` +face -edge`)
  715.     elif op(1,part) = LINE or op(1,part) = WIREFRAME then
  716.        ap := cat(ap, ` -face +edge`)
  717.     fi
  718.     elif type(part,function) and op(0,part) = THICKNESS and type(op(1,part),integer) then
  719.     ap := cat(ap, ` linewidth `, op(1,part));
  720.     fi
  721.   od;
  722.   if color <> `` then
  723.     color := cat( op(1..3, map(v -> cat(convert(v,string),` `), color) ) );
  724.     ap := cat(ap, `\n material { edgecolor `, color, `\n  diffuse `, color, `}\n`);
  725.   fi;
  726.   if ap <> `` then
  727.     ap := cat(` appearance { `, ap, `}`)
  728.   fi;
  729.   RETURN(ap);
  730. end:
  731.  
  732. [`writeoogl`, `gvplot`];
  733.